package utilitarios;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import negocio.NegocioDAO;



public class Bean {
	public static void copiarPropriedades(Object destino, Object origem) {
		Method[] colecaoMetodos = origem.getClass().getDeclaredMethods();
		for (Method metodo : colecaoMetodos) {
			try {
				if (metodo.getName().contains("get")) {
					Object valor = metodo.invoke(origem);
					if (valor instanceof NegocioDAO) {
						// Ambos os atributos são Modelos.
						Method mt = destino.getClass().getDeclaredMethod(
								metodo.getName(), new Class<?>[0]);
						Object valor2 = mt.invoke(destino);
						if (valor2 instanceof NegocioDAO) {
							copiarPropriedades(valor2, valor);
							continue;
						}
					} else {
						String set = metodo.getName().replace("get", "set");
						Method metodoSet = destino.getClass()
								.getDeclaredMethod(set,
										new Class[] { valor.getClass() });
						metodoSet.invoke(destino, new Object[] { valor });
					}
				} else {
					continue;
				}
			} catch (Exception e) {
				//System.out.println("Erro em copiar propriedades: " + e.getMessage());
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	public static boolean equals(Object bean1, Object bean2) {
		// Handle the trivial cases
		if (bean1 == bean2) {
			return true;
		}
		if (bean1 == null) {
			return false;
		}
		if (bean2 == null) {
			return false;
		}

		// Get the class of one of the parameters
		Class clazz = bean1.getClass();

		// Make sure bean1 and bean2 are the same class
		if (!clazz.equals(bean2.getClass())) {
			return false;
		}

		// Iterate through each field looking for differences
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			// setAccessible is great (encapsulation
			// purists will disagree), setting to true
			// allows reflection to have access to
			// private members.
			fields[i].setAccessible(true);
			try {
				Object value1 = fields[i].get(bean1);
				Object value2 = fields[i].get(bean2);
				if ((value1 == null && value2 != null)
						|| (value1 != null && value2 == null)) {
					return false;
				}
				if (value1 != null && value2 != null && !value1.equals(value2)) {
					return false;
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return true;
	}

	@SuppressWarnings("unchecked")
	public static String toString(Object bean) {
		if (bean == null) {
			return "";
		}
		StringBuilder string = new StringBuilder();
		Class clazz = bean.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			fields[i].setAccessible(true);
			string.append(fields[i].getName());
			string.append("=");
			try {
				// Display both the field's type and value
				string.append(fields[i].get(bean)+";");
			} catch (IllegalArgumentException e) {
				return "";
			} catch (IllegalAccessException e) {
				return "";
			}
		}
		return string.toString();
	}

	@SuppressWarnings("unchecked")
	public static Object clone(Object bean) {
		Object clone = null;
		if (bean == null) {
			return null;
		}
		try {
			// Create a new object instance using the same
			// class as the parameter
			clone = bean.getClass().newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		// Wind up the object's superclasses
		for (Class clazz = bean.getClass(); !clazz.equals(Object.class); clazz = clazz
				.getSuperclass()) {
			Field[] fields = clazz.getDeclaredFields();
			for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				try {
					fields[i].set(clone, fields[i].get(bean));
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
		return clone;
	}
}
